package com.company.statistician.noise;

import com.company.statistician.Column;

import java.util.ArrayList;

public class LaplaceNoiser implements Noiser {

    private double epsilon;
    private double sensitivity;

    public LaplaceNoiser(double epsilon, double sensitivity) {
        this.epsilon = epsilon;
        this.sensitivity = sensitivity;
    }

    @Override
    public ArrayList<Column> addNoise(ArrayList<Column> columns) {
        ArrayList<Column> newColumns = new ArrayList<>(columns.size());
        for (int i = 0; i < columns.size(); i++) {
            Column column = columns.get(i);
            double value = column.getValue();
            double newValue = value + laplace_noise(this.sensitivity, this.epsilon);
            Column newColumn = new Column(column.getBeginAt(), column.getEndAt(), newValue);
            newColumns.add(newColumn);
        }
        return newColumns;
    }

    private double laplace_noise(double sensitivity, double epsilon) {
        double beta = sensitivity / epsilon;
        double u1 = Math.random();
        double u2 = Math.random();
        double n_value;
        if (u1 <= 0.5) {
            n_value = -beta * Math.log(1. - u2);
        } else {
            n_value = beta * Math.log(u2);
        }
        return n_value;
    }


}
